﻿module Lhz.Page {
    export class DetailPage<T extends Lhz.Entity.ServiceCenter.DbEntity> extends Page {
        private options: Lhz.Interface.Page.DetailPageOptions<T>;
        sci = new ServiceCenter.Invoker();
        arguments: any;
        private $layout: any;
        private $form: any;
        item: T;
        private dbOperation: boolean;

        constructor(options: Lhz.Interface.Page.DetailPageOptions<T>) {
            super();
            if (this.indexInitialized) {
                this.options = $.extend({
                    layoutSelector: "body",
                    formSelector: "form",
                    buttonOkSelector: "#buttonOk",
                    buttonCancelSelector: "#buttonCancel",
                    queryByPkOperationNo: "queryByPk",
                    addOperationNo: "add",
                    updateOperationNo: "update"
                }, options);
                if (!this.options.getItem) {
                    this.options.getItem = function (dp) {
                        return dp.arguments.item;
                    };
                }
                if (!this.options.getDbOperation) {
                    this.options.getDbOperation = function (dp) {
                        return dp.arguments.dbOperation;
                    };
                }
                this.arguments = this.getDialogArguments();

                if (this.options.initiate) {
                    this.options.initiate(this, function (dp) {
                        dp.dpInitiate();
                    });
                }
                else {
                    this.dpInitiate();
                }
            }
        }

        private dpInitiate() {
            this.$form = $(this.options.formSelector);
            this.buildButton();
            this.buildValidate();
            this.$layout = $(this.options.layoutSelector);
            setTimeout(function (ud: DetailPage<T>) {
                ud.buildLayout();
            }, 0, this);
            var item = this.options.getItem(this);
            this.dbOperation = this.options.getDbOperation(this);
            if (item && this.dbOperation) {
                this.showLoading();
                this.sci.InvokeByInvokeArgument<T>({
                    serviceNo: this.options.serviceNo,
                    operationNo: this.options.queryByPkOperationNo,
                    arguments: [item.Guid, null],
                    successCallback: function (result, data) {
                        var dp: DetailPage<T> = data;
                        dp.item = result.Result;
                        dp.closeLoading();
                        dp.dbInitialized();
                    },
                    data: this
                });
            }
            else {
                this.item = item;
                if (!this.item) {
                    this.item = this.options.createItem(this);
                }
                this.dbInitialized();
            }
        }

        private dbInitialized() {
            if (this.item) {
                this.setItem(this.item);
                this.showInfo();
            }
            if (this.options.initialized) {
                this.options.initialized(this);
            }
        }

        buildValidate() {
            this.$form.validate();
        }

        private buildLayout() {
            this.$layout = this.$layout.layout({
                defaults: {
                    closable: false,
                    resizable: false,
                    spacing_open: 0,
                    paneClass: "ui-widget-content"
                }
            });
        }

        private buildButton() {
            $(this.options.buttonOkSelector).button({ icons: { primary: "ui-icon-check" } }).click(this, function (event) {
                var dp: DetailPage<T> = event.data;
                if (dp.$form.valid()) {
                    var operationNo: string;
                    if (dp.item.Guid) {
                        operationNo = dp.options.updateOperationNo;
                    }
                    else {
                        operationNo = dp.options.addOperationNo;
                        if (dp.dbOperation) {
                            dp.item.Guid = dp.sci.getGuid();
                        }
                        dp.setItem(dp.item);
                    }
                    dp.saveInfo();
                    if (dp.options.saveStart) {
                        dp.options.saveStart(dp);
                    }
                    if (dp.dbOperation) {
                        dp.showLoading();
                        dp.sci.InvokeByInvokeArgument({
                            serviceNo: dp.options.serviceNo,
                            operationNo: operationNo,
                            arguments: [dp.item],
                            successCallback: function (result, data) {
                                var dp: DetailPage<T> = data;
                                dp.closeLoading();
                                alert("操作成功。");
                                dp.closeDialog(true);
                            },
                            data: dp
                        });
                    }
                    else {
                        dp.closeDialog(dp.item, true);
                    }
                }
            });
            $(this.options.buttonCancelSelector).button({ icons: { primary: "ui-icon-cancel" } }).click(this, function (event) {
                var dp: DetailPage<T> = event.data;
                dp.closeDialog();
            });
        }

        setItem(item: T) {
            this.item = item;
        }

        showInfo() {
            for (var mappingOptions of this.options.mappingOptionsArray) {
                if (mappingOptions.show) {
                    mappingOptions.show(this, this.item);
                }
                else {
                    this.setValue(mappingOptions.selector, this.item[mappingOptions.propertyName]);
                }
            }
        }

        saveInfo() {
            for (var mappingOptions of this.options.mappingOptionsArray) {
                if (mappingOptions.save) {
                    mappingOptions.save(this, this.item);
                }
                else {
                    var values = this.getValue(mappingOptions.selector);
                    if (Array.isArray(values)) {
                        values = values[0];
                    }
                    this.item[mappingOptions.propertyName] = values;
                }
            }
        }
    }
}
